package com.google.zxing.client.android.came2;


import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;

import com.google.zxing.Result;

import com.google.zxing.client.android.R;

import java.util.Collection;
import java.util.Map;

import static com.google.zxing.client.android.came2.CameraDecodeHandler.BARCODE_BITMAP;
import static com.google.zxing.client.android.came2.CameraDecodeHandler.BARCODE_SCALED_FACTOR;

public final class CaptureCamra2Handler extends Handler {

    private final ScanActivity activity;
    private State state;
    private final CameraDeviceManager manager;
    private CameraDecodeThread decodeThread;
    public CaptureCamra2Handler(ScanActivity activity, Collection<BarcodeFormat> decodeFormats,
                                Map<DecodeHintType,?> baseHints,
                                String characterSet,CameraDeviceManager manager) {
        this.activity = activity;
        this.manager = manager;
        decodeThread = new CameraDecodeThread(activity,decodeFormats,baseHints,characterSet,null);
        decodeThread.start();
        state = State.SUCCESS;

        manager.startPreview();
        restartPreviewAndDecode();
    }

    private enum State {
        PREVIEW,
        SUCCESS,
        DONE
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        if (msg.what == R.id.restart_preview){
            restartPreviewAndDecode();
        }else if (msg.what == R.id.decode_succeeded){
            Bundle bundle = msg.getData();
            Bitmap barcode = null;
            float scaleFactor = 1.0f;
            if (bundle != null) {
                byte[] compressedBitmap = bundle.getByteArray(BARCODE_BITMAP);
                if (compressedBitmap != null) {
                    barcode = BitmapFactory.decodeByteArray(compressedBitmap, 0, compressedBitmap.length, null);
                    // Mutable copy:
                    barcode = barcode.copy(Bitmap.Config.ARGB_8888, true);
                }
                scaleFactor = bundle.getFloat(BARCODE_SCALED_FACTOR);
            }
            activity.handleDecode((Result) msg.obj, barcode, scaleFactor);
        }else if (msg.what == R.id.decode_failed){
            state = State.PREVIEW;
            manager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
        }else if (msg.what == R.id.return_scan_result){}
    }

    public void quitSynchronously() {
        state = State.DONE;
        manager.stopPreview();
        Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit);
        quit.sendToTarget();
        try {
            // Wait at most half a second; should be enough time, and onPause() will timeout quickly
            decodeThread.join(500L);
        } catch (InterruptedException e) {
            // continue
        }

        // Be absolutely sure we don't send any queued up messages
        removeMessages(R.id.decode_succeeded);
        removeMessages(R.id.decode_failed);
    }

    private void restartPreviewAndDecode() {
        if (state == State.SUCCESS) {
            state = State.PREVIEW;
            manager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
        }
    }
}
